package com.qc31.monitorlib.ui.video

import android.Manifest
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MenuItem
import android.widget.SeekBar
import android.widget.TextView
import androidx.activity.viewModels
import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.GridLayoutManager
import autodispose2.androidx.lifecycle.AndroidLifecycleScopeProvider
import autodispose2.autoDispose
import com.gyf.immersionbar.ktx.immersionBar
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.qc31.baselib.base.BaseActivity
import com.qc31.baselib.interfaces.SimpleSeekBarChangeListener
import com.qc31.baselib.loadsie.EmptyCallback
import com.qc31.baselib.rx.queryThrottle
import com.qc31.baselib.utils.*
import com.qc31.baselib.utils.ActivityResultUtil.launchAct
import com.qc31.baselib.utils.ActivityResultUtil.registerResultOk
import com.qc31.comlib.Keys
import com.qc31.comlib.UrlUtil
import com.qc31.comlib.UserConstant
import com.qc31.comlib.choose.car.ChooseCarActivity
import com.qc31.comlib.entity.RealVideoInfo
import com.qc31.monitorlib.R
import com.qc31.monitorlib.databinding.ActivityRealVideoBinding
import com.qc31.monitorlib.ui.adapter.RealVideoAdapter
import com.qc31.monitorlib.ui.carmonitor.CarRealVideoViewModel
import com.qc31.monitorlib.ui.popup.PopupActivity
import com.qc31.monitorlib.ui.video.observer.ChooseVideoUtil
import com.qc31.monitorlib.ui.video.observer.NeedMutesUtil
import com.tbruyelle.rxpermissions3.RxPermissions
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import java.util.*

/** @Author Jasper @Time 2020/12/3 @Desc 实时视频 */
class RealVideoActivity :
    BaseActivity<ActivityRealVideoBinding>(ActivityRealVideoBinding::inflate) {

    private val mViewModel by viewModels<CarRealVideoViewModel>()
    private val talkHelper by lazy { TalkHelper() }

    private var mAdapter: RealVideoAdapter? = null
    private var loadService: LoadService<Any>? = null
    private var uuid: String = ""

    override fun initView() {
        immersionBar { titleBar(binding.mToolbar) }
        ToolbarHelper.setToolbar(this, R.string.title_monitor_real_video)
        loadService = LoadSir.getDefault().register(binding.recyclerVideo)
        loadService?.setCallBack(EmptyCallback::class.java) { context, view ->
            val empty = view.findViewById<TextView>(R.id.tv_empty)
            empty.text = getString(R.string.hint_toast_choose_car)
        }
        loadService?.showCallback(EmptyCallback::class.java)

        ChooseVideoUtil.instance.setOnVideoIndexListener(object :
            ChooseVideoUtil.OnVideoIndexListener {
            override fun onChange(index: Int) {
                mViewModel.channel = mAdapter?.data?.get(index)?.videoPass ?: ""
                val action = mViewModel.getAction()
                binding.ivLight.isSelected = action.light == 1
                binding.ivWiper.isSelected = action.wiper == 1
            }
        })

        ChooseVideoUtil.instance.setOnTalkListener(object :
            ChooseVideoUtil.OnTalkListener {
            override fun onChange(isTalk: Boolean) {
                isRecord = true
                closeTalk()
            }
        })

        initRecyclerView()
        initIntent()

        mViewModel.toastObserver().autoDispose(scopeProvider).subscribe(this::toastObserver)

        mViewModel.actionLive.observe(this) {
            val action = mViewModel.getAction()
            binding.ivLight.isSelected = action.light == 1
            binding.ivWiper.isSelected = action.wiper == 1
        }

        //上传PCM数据网络失败监听
        talkHelper.talkObserver().observeOn(AndroidSchedulers.mainThread())
            .autoDispose(scopeProvider).subscribe {
                isRecord = true
                closeTalk()
                binding.llRealVideoInfo.isEnabled = true
                binding.lltvControl.isEnabled = true
                binding.llAudio.isVisible = false
            }
    }

    private fun initIntent() {
        if (UserConstant.isRealVideo)return
        val carId = intent.getStringExtra(Keys.INTENT_CAR_ID)

        if (carId == null) {
            launcher.launchAct<ChooseCarActivity>(this) {
                putExtra(Keys.INTENT_IS_VIDEO, true)
            }
            return
        }

        val carName = intent.getStringExtra(Keys.INTENT_PLATE) ?: ""
        val videos = intent.getStringExtra(Keys.INTENT_CAR_VIDEOS) ?: ""
        mViewModel.carId = carId
        mViewModel.videos = videos
        binding.lrvChooseCar.setRightText(carName)
        binding.lrvChooseCar.isEnabled = false
        mAdapter?.carId = mViewModel.carId

        val videoEntitys = mViewModel.handleVideos()
        if (videoEntitys?.isNotEmpty() == true) {
            loadService?.showSuccess()
        }
        mAdapter?.setList(videoEntitys)

    }

    override fun setListener() {
        binding.lrvChooseCar.queryThrottle().autoDispose(scopeProvider).subscribe {
            if (UserConstant.isRealVideo)return@subscribe
            stopVideos()
            binding.lrvChooseCar.setRightText("")
            mViewModel.audioPass = ""
            mViewModel.carId = ""
            mViewModel.clearMap()
            binding.llControl.isVisible = false
            binding.llControl.isEnabled = true
            binding.llRealVideoTalk.isEnabled = true
            binding.llRealVideoInfo.isEnabled = true
            loadService?.showCallback(EmptyCallback::class.java)
            launcher.launchAct<ChooseCarActivity>(this) {
                putExtra(Keys.INTENT_IS_VIDEO, true)
            }
        }

        binding.llRealVideoInfo.setOnClickListener {
            if (mViewModel.carId.isEmpty()) {
                R.string.hint_toast_choose_car.toast(this)
                return@setOnClickListener
            }
            startActivityTo<PopupActivity>(this) {
                putExtra(Keys.INTENT_CAR_ID, mViewModel.carId)
            }
        }

        binding.llRealVideoTalk.setOnClickListener {
            MLog.e("------------llRealVideoTalk-------${mViewModel.isParamsOk()}------------")
            if (mViewModel.isParamsOk()) return@setOnClickListener
            if (isRecord) {
                binding.llRealVideoInfo.isEnabled = false
                binding.lltvControl.isEnabled = false
                getPermissions()
            } else {
                isRecord = true
                closeTalk()
                binding.llRealVideoInfo.isEnabled = true
                binding.lltvControl.isEnabled = true
            }
        }

        binding.lltvControl.setOnClickListener {
            MLog.e("------------lltvControl---------${mViewModel.isParamsOk()}----------")
            if (mViewModel.isParamsOk()) return@setOnClickListener
            val visible = binding.llControl.isVisible
            binding.llRealVideoInfo.isEnabled = visible
            binding.llRealVideoTalk.isEnabled = visible

            binding.llControl.isVisible = !visible
            binding.tvControl.isSelected = !visible
            binding.ivControl.isSelected = !visible
            val action = mViewModel.getAction()
            binding.ivLight.isSelected = action.light == 1
            binding.ivWiper.isSelected = action.wiper == 1
        }

        binding.vUp.setOnClickListener { mViewModel.control(1) }
        binding.vLeft.setOnClickListener { mViewModel.control(3) }
        binding.vCenter.setOnClickListener { mViewModel.control(0) }
        binding.vRight.setOnClickListener { mViewModel.control(4) }
        binding.vDown.setOnClickListener { mViewModel.control(2) }

        binding.ivFocalUp.setOnClickListener {
            mViewModel.changeAction(1, 1)
        }
        binding.ivFocalDown.setOnClickListener {
            mViewModel.changeAction(1, 0)
        }
        binding.ivApertureUp.setOnClickListener {
            mViewModel.changeAction(2, 0)
        }
        binding.ivApertureDown.setOnClickListener {
            mViewModel.changeAction(2, 1)
        }
        binding.ivZoomUp.setOnClickListener {
            mViewModel.changeAction(5, 0)
        }
        binding.ivZoomDown.setOnClickListener {
            mViewModel.changeAction(5, 1)
        }

        binding.ivLight.setOnClickListener {
            val light = mViewModel.getAction().light
            if (light == 0) {
                mViewModel.changeAction(4, 1)
            } else {
                mViewModel.changeAction(4, 0)
            }
        }

        binding.ivWiper.setOnClickListener {
            val wiper = mViewModel.getAction().wiper
            if (wiper == 0) {
                mViewModel.changeAction(3, 1)
            } else {
                mViewModel.changeAction(3, 0)
            }
        }

        binding.sbSpeed.setOnSeekBarChangeListener(object : SimpleSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                super.onProgressChanged(seekBar, progress, fromUser)
                mViewModel.speed = seekBar?.progress ?: 0
                binding.tvSpeedNum.text = mViewModel.speed.toString()
            }
        })
    }

    private var isRecord = true
    private fun getPermissions() {
        RxPermissions(this).request(
            Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE
        ).autoDispose(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY))
            .subscribe {
                if (it) {
                    isRecord = false
                    if (mViewModel.audioPass.isNullOrEmpty()) return@subscribe
                    binding.tvRealVideoTalk.isSelected = true
                    binding.tvRealVideoTalk.setText(R.string.desc_video_car_talk_close)
                    binding.ivRealVideoTalk.isSelected = true
                    uuid = UUID.randomUUID().toString()
                    initVideo()
                }
            }
    }


    private fun initRecyclerView() {
        binding.recyclerVideo.layoutManager = GridLayoutManager(this, 2)
        mAdapter = RealVideoAdapter(UserConstant.current_userId, mViewModel.carId)
        binding.recyclerVideo.adapter = mAdapter
        val view =
            LayoutInflater.from(this).inflate(R.layout.food_view, binding.recyclerVideo, false)
        mAdapter!!.addFooterView(view)
    }

    /** 停止播放并初始化状态 */
    private fun stopVideos() {
        mViewModel.audioPass = ""
        mAdapter?.setList(null)
        RealVideoManager.clearAllVideo()
        closeVideos()
        closeTalk()
        NeedMutesUtil.instance.clearAll()
        ChooseVideoUtil.instance.clearAll()
        binding.ivControl.isSelected = false
        binding.tvControl.isSelected = false
    }


    /** 关闭播放 */
    private fun closeVideos() {
        if (mAdapter != null) {
            val entitys: MutableList<RealVideoInfo> = mAdapter?.data ?: return
            for (entity in entitys) {
                if (entity.uuid.isEmpty()) continue
                mViewModel.closeVideo(entity.uuid)
            }
        }
    }

    private var isBackground = false
    override fun onPause() {
        super.onPause()
        isBackground = false
        binding.recyclerVideo.postDelayed({
            if (!isAppOnForeground(this)) {
                isBackground = true
                RealVideoManager.clearAllVideo(audioPlayer?.getKey())
                closeVideos()
            }
        }, 500)

    }

    override fun onDestroy() {
        super.onDestroy()
        NeedMutesUtil.instance.clearAll()
        ChooseVideoUtil.instance.clearAll()
        stopVideos()
        talkHelper.destroy()
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == android.R.id.home) {
            if (RealVideoManager.backFromWindowFull(this, mAdapter?.fullKey ?: ""))
                return true
        }
        return super.onOptionsItemSelected(item)
    }


    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (RealVideoManager.backFromWindowFull(this, mAdapter?.fullKey ?: ""))
                return true
        }
        return super.onKeyDown(keyCode, event)
    }

    private val launcher = registerResultOk { result ->
        result.data?.let {
            val carId = it.getStringExtra(Keys.INTENT_CAR_ID) ?: ""
            val carName = it.getStringExtra(Keys.INTENT_CAR_NAME) ?: ""
            val videos = it.getStringExtra(Keys.VIDEO) ?: ""
            binding.lrvChooseCar.setRightText(carName)
            mViewModel.carId = carId
            mViewModel.videos = videos
            mAdapter?.carId = mViewModel.carId
            val videoEntitys = mViewModel.handleVideos()
            if (videoEntitys?.isNotEmpty() == true) {
                loadService?.showSuccess()
            }
            mAdapter?.setList(videoEntitys)
        }
    }

    //////////////////////////////////////////////对讲/////////////////////////////////////////////////

    /** 获取播放视频参数 */
    private fun getPlayParams(): String {
        return "${UrlUtil.mVideoHost}/httpflv.talk_open.$uuid.${UserConstant.current_userId}.${mViewModel.carId}.${mViewModel.audioPass}"
    }

    private var audioPlayer: AudioPlayer? = null
    private fun initVideo() {
        binding.llAudio.isVisible = true
        binding.tvAudio.setText(R.string.toast_audio_link)
        audioPlayer = audioPlayer ?: AudioPlayer(this)

        audioPlayer?.run {
            attachObserver()
            setMute(false)
            setUp(getPlayParams(), false, "video")
            setAudioCallBack(object : AudioPlayer.AudioCallBack {
                override fun finishTalk() {
                    binding.tvAudio.setText(R.string.toast_audio_close)
                    closeAudioVideo()

                }

                override fun success() {
                    talkHelper.start("${UrlUtil.mVideoHost}/microphone.$uuid")
                    binding.tvAudio.setText(R.string.toast_audio_talking)
                }

                override fun failure() {
                    binding.tvAudio.setText(R.string.toast_audio_faile)
                    binding.tvAudio.postDelayed({
                        closeAudioVideo()
                    }, 2000)
                }
            })
            startPlayLogic()
        }

    }

    private fun closeTalk() {
        closeAudioVideo()
        mViewModel.closeAudio(uuid)
    }

    private fun closeAudioVideo() {
        talkHelper.stopRecord()
        binding.tvRealVideoTalk.isSelected = false
        binding.llAudio.isVisible = false
        binding.tvRealVideoTalk.setText(R.string.desc_video_car_talk_open)
        binding.ivRealVideoTalk.isSelected = false
        audioPlayer?.releaseVideos()
        audioPlayer?.release()
        audioPlayer = null
    }
}